class Page < ActiveRecord::Base
  attr_reader :page_html
  has_many :page_elements, :include=>:content, :order=>"area_name, position ASC" do
    def of_area (area_name)
      find_all "area_name = '#{area_name}'"
    end
  end
  # returns an array of strings with all the area_names associated to the elements of this page
  has_many :areas, :class_name=>"PageElement", :select=>"area_name", :group=>"area_name"
  has_many :contents, :through => :page_elements
  acts_as_urlnameable :title, :overwrite=>true, :message=>'is unavailable.', :validate=>:class
  
  
  THEMES_BASE_PATH = RAILS_ROOT+"/public/themes/"
  
  def render( mode = :show )
    @page_html = theme_body
    fill_areas do |area_name|
      area_html = ""
      area_html << "<div class='compages_area' id='area_#{ area_name }'>" if mode == :edit
      for page_element in page_elements.of_area area_name
        unless page_element.content.nil?
          area_html << "<div class='compages_element' id='element_#{ page_element.id }'>" if mode == :edit
          area_html << page_element.content.body_to_html
          area_html << "</div>" if mode == :edit
        else
          page_element.destroy
        end
      end
      area_html << "</div>" if mode == :edit
      area_html
    end
    fill_theme_vars
  end
  
  # renders the whole page with its theme and contents
  def to_html
    @page_html = theme_body
    # subsitutes areas definition (like %%area:my_area_name%%)
    # with the html for the area elements
    @page_html.gsub!( %r{%%area:([a-z_]+)%%} ) do ||
      area_name, area_html = $1, ""
      for page_element in page_elements.of_area area_name
        area_html = page_element.content.body_to_html
      end
      area_html
    end
    fill_theme_vars
  end
  
  def fill_areas
    # subsitute areas definition (like %%area:myareaname%%) 
    # with the html for the area elements
    @page_html.gsub!( %r{%%area:([a-z_]+)%%} ) do
      area_name = $1
      yield area_name
    end
    return @page_html
  end
  
  def fill_theme_vars
    # subsitutes some other %%-style "variables" (see above)
    @page_html.gsub!( %r{%%([a-z_]+):([a-z_]*)%%} ) do
      case $1
      when "page"
        case $2
        when "title"
          title
        when "site_name"
          GlobalSettings[:site_name].value
        end
      when "theme"
        THEMES_BASE_PATH[(RAILS_ROOT+"/public").length..-1] + theme_name if $2 == "path"
      end
    end
    return @page_html
  end
  
  def area_names #of the page
    theme_areas #areas.collect {|area| area.area_name }.compact
  end
  
  # returns the theme main file code
  def theme_body
    Page.theme_body( theme_name )
  end
  def theme_areas
     Page.theme_areas( theme_name )
  end
  
  class << self
    # returns the theme main file code
    def theme_body (theme_name)
      File.open( THEMES_BASE_PATH + theme_name + "/index.html" ).read
    end
  
    # returns an array with all the available theme names
    def available_themes
      Dir.entries(THEMES_BASE_PATH).collect {|f| f.gsub("_", "_") unless (f =~ /\..*/ ) }.compact
    end
  
    def theme_areas (theme_name)
      areas_colection = []
      (Page.theme_body theme_name).gsub %r{%%area:([a-z_]+)%%} do |match|
        areas_colection << $1
      end
      return areas_colection
    end
  end
end
